﻿Imports System
Imports System.Collections.Specialized
Imports System.Security.Cryptography
Imports System.Text
Imports System.Web

Namespace Pic
    Public Class SecureQueryString
        Inherits NameValueCollection
        Private Const cryptoKey As String = "denemekeyforquerys"
        Private ReadOnly IV As Byte() = New Byte(7) {240, 3, 45, 29, 0, 76, 173, 59}

        Sub New()

        End Sub

        Sub New(ByVal encStr As String)
            Deserialize(Decrypt(encStr))
        End Sub

        Public ReadOnly Property EncryptedString() As String
            Get
                Return HttpUtility.UrlEncode(Encrypt(Serialize()))
            End Get
        End Property

        Public Overrides Function ToString() As String
            Return EncryptedString
        End Function

        Private Function Encrypt(ByVal serQS As String) As String
            Dim buffer As Byte() = Encoding.ASCII.GetBytes(serQS)
            Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
            Dim md5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
            des.Key = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(cryptoKey))
            des.IV = IV
            Return Convert.ToBase64String(des.CreateEncryptor.TransformFinalBlock(buffer, 0, buffer.Length))
        End Function

        Private Function Decrypt(ByVal encQS As String) As String
            Try
                Dim buffer As Byte() = Convert.FromBase64String(encQS)
                Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
                Dim MD5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
                des.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(cryptoKey))
                des.IV = IV
                Return Encoding.ASCII.GetString(des.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length()))
            Catch ex As CryptographicException
                Throw New InvalidQueryStringException
            Catch ex As FormatException
                Throw New InvalidQueryStringException
            End Try
        End Function

        Private Sub Deserialize(ByVal decQS As String)
            Dim nameValuePairs As String() = decQS.Split("&")
            Dim i As Integer
            For i = 0 To nameValuePairs.Length - 1
                Dim nameValue As String() = nameValuePairs(i).Split("=")
                If nameValue.Length = 2 Then
                    Me.Add(nameValue(0), nameValue(1))
                End If
            Next
        End Sub

        Private Function Serialize() As String
            Dim sb As StringBuilder = New StringBuilder
            Dim key As String
            For Each key In Me.AllKeys
                sb.Append(key)
                sb.Append("=")
                sb.Append(Me(key))
                sb.Append("&")
            Next key
            Return sb.ToString
        End Function
    End Class
End Namespace
